home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_005 / mandelbrotsrc / mand3.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  16KB  |  577 lines

  1.  
  2. /*
  3.                   MAND3.C - Control routines
  4.              Mandelbrot Self-Squared Dragon Generator
  5.                     For the Commodore Amiga
  6.                          Version 2.01
  7.  
  8.              Copyright (C) 1985, Robert S. French
  9.             Vastly Enhanced by =RJ Mical=  1985/86
  10.             Copyright (C) 1986,  =Robert J. Mical=
  11.                  Placed in the Public Domain
  12.  
  13.  
  14. This program may be distributed free of charge as long as the above
  15. notice is retained.
  16.  
  17. */
  18.  
  19.  
  20. #include "mand.h"
  21.  
  22.  
  23. extern int MathBase, MathTransBase;
  24.  
  25. extern struct Menu MainMenu[MENU_COUNT];
  26. extern struct MenuItem OptionsItems[OPTIONS_COUNT];
  27.  
  28. extern SHORT Color0, Color1, Color2;
  29. extern SHORT UserPalette[29];
  30.  
  31. extern BOOL SavePicture();
  32.  
  33.  
  34. /*----------------------*/
  35. /* Graphics definitions */
  36.  
  37. extern struct   GfxBase       *GfxBase;
  38. extern struct   IntuitionBase *IntuitionBase;
  39.  
  40. struct   RastPort      *rp,*rp2;
  41. struct   ViewPort      *vp;
  42.  
  43. struct TextAttr TextFont =
  44.     {
  45.     "topaz.font", /* Standard system font */
  46.     8,    0,    0
  47.     };
  48.  
  49. struct   Window        *w,*w2, ColorWindow;
  50. struct   Screen        *screen;
  51. struct   IntuiMessage  *message;
  52.  
  53. struct NewScreen ns = {
  54.    0, 0,                               /* start position                */
  55.    320, 200, 6,                        /* width, height, depth          */
  56.    0, 1,                               /* detail pen, block pen         */
  57.    HAM,                                /* Hold and Modify ViewMode      */
  58.    CUSTOMSCREEN,                       /* screen type                   */
  59.    &TextFont,                          /* font to use                   */
  60.    "",                                 /* default title for screen      */
  61.    NULL                                /* pointer to additional gadgets */
  62.    };
  63.  
  64. struct NewWindow nw = {
  65.    0, 0,                          /* start position                */
  66.    320, 200,                      /* width, height                 */
  67.    -1, -1,                        /* detail pen, block pen         */
  68.    MOUSEBUTTONS | MENUPICK | INTUITICKS,
  69.                                   /* IDCMP flags                   */
  70.    ACTIVATE | BORDERLESS | BACKDROP,
  71.                                   /* window flags                  */
  72.    NULL,                          /* pointer to first user gadget  */
  73.    NULL,                          /* pointer to user checkmark     */
  74.    NULL,                          /* window title                  */
  75.    NULL,                          /* pointer to screen (set below) */
  76.    NULL,                          /* pointer to superbitmap        */
  77.    0, 0, 320, 200,                /* ignored since not sizeable    */
  78.    CUSTOMSCREEN                   /* type of screen desired        */
  79. };
  80.  
  81. struct NewWindow aw = {
  82.    0, 10,
  83.    100, 70,
  84.    -1, -1,
  85.    NULL,
  86.    WINDOWDRAG|WINDOWSIZING|SMART_REFRESH,
  87.    NULL,
  88.    NULL,
  89.    "Analysis",
  90.    NULL,
  91.    NULL,
  92.    0, 0, 320, 200,
  93.    CUSTOMSCREEN
  94. };
  95.  
  96. long last_color;
  97.  
  98. BOOL SettingCenter, SettingBoxSize, SetBoxProportional;
  99.  
  100. /*----------------------------------*/
  101. /* Miscellaneous Global Definitions */
  102.  
  103. extern union kludge {
  104.    float f;
  105.    int i;
  106. } start_r,end_r,start_i,end_i;  /* Block bounds for set */
  107. extern int max_x,max_y;  /* Graphics window size */
  108. extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
  109. extern int color_inset,func_num;
  110.  
  111. extern int v_starty,max_mem, max_mem_y;
  112. extern long v_offset;
  113. extern UWORD *color_table,*v_mand_store;
  114.  
  115. extern int modified,want_read;
  116.  
  117. extern FILE *console,*v_fp,*redir_fp;
  118.  
  119. extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
  120. extern SHORT ZoomBoxStartX, ZoomBoxStartY;
  121.  
  122.  
  123. open_winds()
  124. {
  125.    int i,color;
  126.  
  127.    nw.Width = max_x;
  128.    nw.Height = max_y+STARTY;
  129.  
  130.    if (color_mode & NOT_HOLDANDMODIFY) {
  131.       ns.ViewModes = NULL;
  132.       ns.Depth = 5;
  133.    }
  134.    else {
  135.       ns.ViewModes = HAM;
  136.       ns.Depth = 6;
  137.    }
  138.  
  139.    if (color_mode & INTERLACE_MODE) {
  140.       ns.Height = 400;
  141.    }
  142.    else
  143.       ns.Height = 200;
  144.  
  145.    if (color_mode & HIRES_MODE) {
  146.       ns.Width = 640;
  147.       ns.ViewModes |= HIRES;
  148.       ns.Depth = 4;
  149.    }
  150.    else
  151.       ns.Width = 320;
  152.  
  153.    screen = (struct Screen *)OpenScreen(&ns);
  154.    if (screen == NULL) {
  155.       fputs("Can't open new screen!\n",console);
  156.       return (1);
  157.    }
  158.  
  159.    ShowTitle(screen,FALSE);
  160.  
  161.    nw.Screen = screen;
  162.    w = (struct Window *)OpenWindow(&nw);
  163.    if (w == NULL) {
  164.       CloseScreen(screen);
  165.       fputs("Can't open new window!\n",console);
  166.       return (1);
  167.    }
  168.  
  169.    /* Until we're done drawing the primary display, cripple the menu system */
  170.    MainMenu[MENU_OPTIONS].NextMenu = NULL;
  171.    MainMenu[MENU_OPTIONS].FirstItem = &OptionsItems[OPTIONS_STOP];
  172.    SetMenuStrip(w, &MainMenu[MENU_OPTIONS]);
  173.  
  174.    vp = &screen->ViewPort;
  175.    rp = w->RPort;
  176.  
  177.    SetDrMd(rp,JAM1);
  178.    SetBPen(rp, 0);
  179.  
  180.    /* leave registers 0 and 1 alone, set two to black, set the others
  181.     * according to the user's design
  182.     */
  183.    SetRGB4(vp, 0, (Color0 >> 8) & 0xf, (Color0 >> 4) & 0xf, Color0 & 0xf);
  184.    SetRGB4(vp, 1, (Color1 >> 8) & 0xf, (Color1 >> 4) & 0xf, Color1 & 0xf);
  185.    SetRGB4(vp, 2, (Color2 >> 8) & 0xf, (Color2 >> 4) & 0xf, Color2 & 0xf);
  186.    for (i = 3; i <= 31; i++) {
  187.       UserPalette[i - 3] = 
  188.             color = *(color_table + color_offset + (i - 2) * color_inc);
  189.       SetRGB4(vp, i, (color >> 8) & 0xf, (color >> 4) & 0xf, color & 0xf);
  190.    }
  191.  
  192.    return (0);
  193. }
  194.  
  195. void wait_close()
  196. {
  197.    ULONG class;
  198.    USHORT code;
  199.  
  200.    if (redir_fp)
  201.       {
  202.       Delay(600);
  203.       CloseDisplay();
  204.       return;
  205.       }
  206.  
  207.    SettingCenter = SettingBoxSize = FALSE;
  208.  
  209.    for (EVER)
  210.       {
  211.       Wait((1 << w->UserPort->mp_SigBit));
  212.       while (message = (struct IntuiMessage *)GetMsg(w->UserPort))
  213.          {
  214.          class = message->Class;
  215.          code  = message->Code;
  216.          ReplyMsg(message);
  217.  
  218.          switch (class)
  219.             {
  220.             case MENUPICK:
  221.                switch MENUNUM(code)
  222.                   {
  223.                   case MENU_PROJECT:
  224.                      if (ProjectMenu(code)) return;
  225.                      break;
  226.                   case MENU_OPTIONS:
  227.                      if (DisplayMenu(code)) return;
  228.                      break;
  229.                   case MENU_ZOOM:
  230.                      if (ZoomMenu(code)) return;
  231.                      break;
  232.                   }
  233.                break; /* breaks MENUPICK switch statement */
  234.             case INTUITICKS:
  235.               code = NULL;
  236.             case MOUSEBUTTONS:
  237.               if (SettingCenter)
  238.                  {
  239.                  DrawZoomCenter();
  240.          if (code == SELECTDOWN) 
  241.                     {
  242.                     SettingCenter = FALSE;
  243.                     DrawDisplayCenter();
  244.             }
  245.                  else
  246.                     {
  247.             ZoomCenterX = w->MouseX;
  248.             ZoomCenterY = w->MouseY;
  249.                     DrawZoomCenter();
  250.                     }
  251.                  }
  252.               else if (SettingBoxSize)
  253.                  {
  254.                  DrawZoomBox();
  255.          if (code == SELECTDOWN) SettingBoxSize = FALSE;
  256.                  else
  257.                     {
  258.                     RecalcZoomBox();
  259.                     DrawZoomBox();
  260.                     }
  261.                  }
  262.               break;
  263.             }
  264.          }
  265.       }
  266. }
  267.  
  268.  
  269. anal_mand()
  270. {
  271.    union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,const0,const1,const2,const4;
  272.    union kludge const12,temp,temp2,temp3;
  273.    int count,x,y,width,height,last_x,last_y,select,lines;
  274.    ULONG class;
  275.    USHORT code;
  276.  
  277.    if (disp_mand())
  278.       return (1);
  279.  
  280.    x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
  281.    y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
  282.  
  283.    const0.i = SPFlt(0);
  284.    const1.i = SPFlt(1);
  285.    const2.i = SPFlt(2);
  286.    const4.i = SPFlt(4);
  287.    const12.i = SPDiv(SPFlt(2),SPFlt(1));
  288.  
  289.    last_x = -1;
  290.    last_y = -1;
  291.    select = 0;
  292.    lines = 0;
  293.  
  294.    aw.Screen = screen;
  295.    w2 = (struct Window *)OpenWindow(&aw);
  296.    if (w2 == NULL)
  297.    {
  298.       CloseDisplay();
  299.       fputs("Can't open analyzing window\n",console);
  300.       return (1);
  301.    }
  302.  
  303.    rp2 = w2->RPort;
  304.  
  305.    SetDrMd(rp2,JAM1);
  306.    SetBPen(rp2, 0);
  307.  
  308.    SetAPen(rp2, 1);
  309.    RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  310.  
  311.    for (EVER) {
  312.       if (message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
  313.          class = message->Class;
  314.          code  = message->Code;
  315.          ReplyMsg(message);
  316.  
  317.          if (class == CLOSEWINDOW) {
  318.             CloseWindow(w2);
  319.             CloseDisplay();
  320.             return (0);
  321.          }
  322.          if (class == MOUSEBUTTONS)
  323.             if (code == SELECTDOWN) {
  324.                if (w->MouseY < STARTY)
  325.                   lines = !lines;
  326.                else
  327.                   select = TRUE;
  328.             }
  329.             else if (code == SELECTUP)
  330.                select = FALSE;
  331.       }
  332.       if ((last_x != w->MouseX || last_y != w->MouseY) && select &&
  333.           w->MouseX < max_x && w->MouseY >= STARTY && w->MouseY < max_y+STARTY) {
  334.          last_x = w-> MouseX;
  335.          last_y = w-> MouseY;
  336.          SetAPen(rp2,1);
  337.          RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  338.          width = RIGHTW2 - LEFTW2 - 6;
  339.          height = BOTTOMW2 - TOPW2 - 4;
  340.          SetAPen(rp2,3);
  341.          Move(rp2,LEFTW2+2,TOPW2+height/2+2);
  342.          Draw(rp2,RIGHTW2-2,TOPW2+height/2+2);
  343.          Move(rp2,LEFTW2+width/2+3,TOPW2+2);
  344.          Draw(rp2,LEFTW2+width/2+3,BOTTOMW2-2);
  345.          SetAPen(rp2,2);
  346.          if (func_num == 0)
  347.             z_r.i = const0.i;
  348.          else
  349.             z_r.i = const12.i;
  350.          z_i.i = const0.i;
  351.          u_r.i = SPAdd(start_r.i,SPMul(SPFlt(last_x),x_gap.i));
  352.          u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-(last_y-STARTY)-1),y_gap.i));
  353.          count = 0;
  354.          for (count=0;SPFix(SPAdd(SPMul(z_r.i,z_r.i),SPMul(z_i.i,z_i.i)))<4&&(count<max_count);count++) {
  355.  
  356.             temp.i = SPDiv(const4.i,SPMul(z_r.i,SPFlt(width)));
  357.             x = SPFix(temp.i);
  358.             temp.i = SPDiv(const4.i,SPMul(z_i.i,SPFlt(height)));
  359.             y = SPFix(temp.i);
  360.  
  361.             if (!lines)
  362.                if (x != 0 || y != 0)
  363.                   WritePixel(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  364.                else ;
  365.             else
  366.                if (count == 0)
  367.                   Move(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  368.                else
  369.                   Draw(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  370.  
  371.             if (func_num == 0) {  /* z = z^2-u */
  372.                temp.i = SPSub(u_r.i,SPSub(SPMul(z_i.i,z_i.i),SPMul(z_r.i,z_r.i)));
  373.                z_i.i = SPSub(u_i.i,SPMul(SPMul(const2.i,z_r.i),z_i.i));
  374.                z_r = temp;
  375.             }
  376.             else if (func_num == 1) {  /* z = uz(1-z) */
  377.                temp2.i = SPSub(z_r.i,const1.i);
  378.                temp3.i = SPNeg(z_i.i);
  379.                temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
  380.                z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
  381.                z_r = temp;
  382.                temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
  383.                z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
  384.                z_r = temp;
  385.             }
  386.          }
  387.       }
  388.    }
  389. }
  390.  
  391. ZoomAlongDarling(rzoom, izoom)
  392. int rzoom, izoom;
  393. {
  394.    union kludge center,distance,scale;
  395.  
  396.       scale.i = rzoom;
  397.       distance.i = SPDiv(SPFlt(2),SPSub(start_r.i,end_r.i));
  398.       center.i = SPAdd(start_r.i,distance.i);
  399.       scale.i = SPMul(scale.i,distance.i);
  400.       start_r.i = SPSub(scale.i,center.i);
  401.       end_r.i = SPAdd(scale.i,center.i);
  402.  
  403.       scale.i = izoom;
  404.       distance.i = SPDiv(SPFlt(2),SPSub(start_i.i,end_i.i));
  405.       center.i = SPAdd(start_i.i,distance.i);
  406.       scale.i = SPMul(scale.i,distance.i);
  407.       start_i.i = SPSub(scale.i,center.i);
  408.       end_i.i = SPAdd(scale.i,center.i);
  409. }
  410.  
  411.  
  412.  
  413. int ProjectMenu(code)
  414. ULONG code;
  415. /* if this function calls gen_mand() and it returns non-zero, return a
  416.  * non-zero to the caller, else return zero
  417.  */
  418. {
  419.     ULONG TimeSecs, TimeMicros;
  420.     UBYTE namebuffer[31], numberbuffer[31];
  421.     SHORT namelength;
  422.  
  423.     switch ITEMNUM(code)
  424.        {
  425.        case PROJECT_SAVEPICTURE:
  426.       CurrentTime(&TimeSecs, &TimeMicros);
  427.       stcu_d(&numberbuffer[0], TimeSecs, 31);
  428.       strcpy(&namebuffer[0], "MandPic.");
  429.       namelength = (31 - 1) - strlen(&namebuffer[0]);
  430.       if (namelength > 4) namelength = 4;
  431.       strncat(&namebuffer[0], &numberbuffer[0], namelength);
  432.       strcat(&namebuffer[0], ".");
  433.       stcu_d(&numberbuffer[0], TimeMicros, 31);
  434.       namelength = (31 - 1) - strlen(&namebuffer[0]);
  435.       if (namelength > 1) namelength = 1;
  436.       strncat(&namebuffer[0], &numberbuffer[0], namelength);
  437.       fprintf(console, "*** NAME OF YOUR FILE: %s\n", &namebuffer[0]);
  438.       ScreenToBack(screen);
  439.       if (SavePicture(&namebuffer[0])) ScreenToFront(screen);
  440.       else fprintf(console, "LeftAMIGA-M will redisplay your picture\n");
  441.       break;
  442.        }
  443.     return(0);
  444. }
  445.  
  446.  
  447. int DisplayMenu(code)
  448. ULONG code;
  449. /* if this function calls gen_mand() and it returns non-zero, return a
  450.  * non-zero to the caller, else return zero
  451.  */
  452. {
  453.     switch ITEMNUM(code)
  454.        {
  455.        case OPTIONS_QUARTER:
  456.       if (color_mode & HIRES_MODE) max_x = 640 / 4;
  457.       else max_x = 320 / 4;
  458.       if (color_mode & INTERLACE_MODE) max_y = 400 / 4;
  459.       else max_y = 200 / 4;
  460.       max_mem = max_mem_y * MAXX;
  461.       max_mem /= max_x;
  462.       if (gen_mand()) return(1);
  463.       break;
  464.        case OPTIONS_FULL:
  465.       if (color_mode & HIRES_MODE) max_x = 640;
  466.       else max_x = 320;
  467.       if (color_mode & INTERLACE_MODE) max_y = 400;
  468.       else max_y = 200;
  469.       max_mem = max_mem_y * MAXX;
  470.       max_mem /= max_x;
  471.  
  472.       /* intentionally fall into GENERATE */
  473.        case OPTIONS_GENERATE:
  474.       if (gen_mand()) return(1);
  475.       break;
  476.        case OPTIONS_CLOSE:
  477.       CloseDisplay();
  478.       fclose(v_fp);
  479.       v_fp = NULL;
  480.       return(1);
  481.        case OPTIONS_COLORS:
  482.       DoColorWindow();
  483.       break;
  484.        }
  485.     return(0);
  486. }
  487.  
  488.  
  489. int ZoomMenu(code)
  490. ULONG code;
  491. /* if this function calls gen_mand() and it returns non-zero, return a
  492.  * non-zero to the caller, else return zero
  493.  */
  494. {
  495.     union kludge center, distance, scale;
  496.  
  497.     switch ITEMNUM(code)
  498.        {
  499.        case ZOOM_SETCENTER:
  500.       if (NOT SettingCenter)
  501.          {
  502.          ZoomCenterX = w->MouseX;
  503.          ZoomCenterY = w->MouseY;
  504.          DrawDisplayCenter();
  505.          DrawZoomCenter();
  506.          SettingCenter = TRUE;
  507.          }
  508.       break;
  509.        case ZOOM_SIZEBOX:
  510.        case ZOOM_SIZEPROP:
  511.       if (NOT SettingBoxSize)
  512.          {
  513.          if (ITEMNUM(code) == ZOOM_SIZEPROP) SetBoxProportional = TRUE;
  514.          else SetBoxProportional = FALSE;
  515.          SettingBoxSize = TRUE;
  516.          RecalcZoomBox();
  517.          DrawZoomBox();
  518.          }
  519.       break;
  520.        case ZOOM_ZOOMIN:
  521.        case ZOOM_ZOOMIN10:
  522.       /* first, get distance equal to the current size 
  523.        * of a single pixel width 
  524.        */
  525.       distance.i = SPSub(start_r.i,end_r.i);
  526.       distance.i = SPDiv(SPFlt(max_x), distance.i);
  527.       /* center equals the number of pixels from the
  528.        * center of the display to the zoom center
  529.        */
  530.       center.i = SPSub(SPFlt(max_x >> 1), SPFlt(ZoomCenterX));
  531.       /* scale equals the real displacement from the
  532.        * center of the display to the zoom center
  533.        */
  534.       scale.i = SPMul(distance.i, center.i);
  535.       /* move the real origin to here */
  536.       start_r.i = SPAdd(scale.i,start_r.i);
  537.       end_r.i = SPAdd(scale.i,end_r.i);
  538.  
  539.       /* now do it all again for the irrational axis */
  540.       distance.i = SPSub(start_i.i,end_i.i);
  541.       distance.i = SPDiv(SPFlt(max_y), distance.i);
  542.       /* the signs are reversed to swap the sign */
  543.       center.i = SPSub(SPFlt(ZoomCenterY), SPFlt(max_y >> 1));
  544.       scale.i = SPMul(distance.i, center.i);
  545.       /* move the real origin to here */
  546.       start_i.i = SPAdd(scale.i,start_i.i);
  547.       end_i.i = SPAdd(scale.i,end_i.i);
  548.  
  549.       /* next, get the zoom-in scale
  550.        * if we're using the frame, then get the 
  551.        * proportion of the box to the display;
  552.        * else if we're zooming in by 10, get that scale
  553.        */
  554.       if (ITEMNUM(code) == ZOOM_ZOOMIN)
  555.          scale.i = SPDiv(SPFlt(max_x), SPFlt(ZoomBoxSizeX));
  556.       else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  557.       ZoomAlongDarling(scale.i, SPFlt(1));
  558.       if (ITEMNUM(code) == ZOOM_ZOOMIN)
  559.          scale.i = SPDiv(SPFlt(max_y), SPFlt(ZoomBoxSizeY));
  560.       else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  561.       ZoomAlongDarling(SPFlt(1), scale.i);
  562.  
  563.       if (gen_mand()) return(1);
  564.       break;
  565.        case ZOOM_ZOOMOUT2:
  566.       ZoomAlongDarling(SPFlt(2), SPFlt(2));
  567.       if (gen_mand()) return(1);
  568.       break;
  569.        case ZOOM_ZOOMOUT10:
  570.       ZoomAlongDarling(SPFlt(10), SPFlt(10));
  571.       if (gen_mand()) return(1);
  572.       break;
  573.        }
  574.    return(0);
  575. }
  576.  
  577.